package com.cictec.middleware.gps.caculate;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import com.cictec.middleware.commons.utils.DateUtils;
import com.cictec.middleware.commons.utils.PMSUtils;
import com.cictec.middleware.commons.utils.PropertiesUtils;
import com.cictec.middleware.core.entity.BusTimingPointSupply;
import com.cictec.middleware.gps.engine.service.DataStorageToRedisService;
import com.cictec.middleware.gps.service.BusTimingPointService;

public abstract class BusMileageCaculate {

	@Autowired
	protected DataStorageToRedisService dataStorageToRedisService;
	@Autowired
	protected BusTimingPointService busTimingPointService;
	
	public abstract void caculateMileage(String date, List<BusTimingPointSupply> supplyList);
	
	/**
	 * 【里程计算】计算指定日期所有设备里程
	 * @param date
	 */
	public void caculateByDate(String date){
		
		// 获取指定日期所有
		List<BusTimingPointSupply> supplyList = getBusPosition(date, false);
				
		caculateMileage(date, supplyList);
	}
	
	/**
	 * 【里程计算】计算指定日期、及所有补传的设备【多天内有补传数据的设备】的里程
	 * @param date
	 */
	public void caculateByDateAndSupply(String date){
		
		// 获取指定日期，及所有带有补传标识的
		List<BusTimingPointSupply> supplyList = getBusPosition(date, true);
		
		caculateMileage(date, supplyList);
	}
	
	
	/**
	 * 【里程计算】计算指定设备的里程
	 * @param date
	 * @param devCodeList	设备编号数组
	 */
	public void caculateByDevCode(String date, List<String> devCodeList) {

		List<BusTimingPointSupply> supplyList = getBusPosition(date, false);
		List<BusTimingPointSupply> devCodeSupplyList = new ArrayList<BusTimingPointSupply>();
		for (String devCode : devCodeList) {
			for (BusTimingPointSupply supply : supplyList) {
				if(date.equals(supply.getSupDate()) && devCode.equals(supply.getSupDevCode())){
					devCodeSupplyList.add(supply);
				}
			}
		}

		caculateMileage(date, devCodeSupplyList);
	}
	
	/**
	 * 获取数据上传标识（设备有数据上传的设备）
	 * @param date				日期
	 * @param isSupply 			true:只查询有补传记录的，false：所有
	 * @return
	 */
	protected List<BusTimingPointSupply> getBusPosition(String date, boolean isSupply) {

		if (isSupply) {
			// 查询补传的设备，date为null时候查询所有补传的设备
			return getBusPositionSupply(date);
		}
		// 查询所有设备，，date为null时候查询所有的设备
		return getBusPosition(date);
	}
	
	private List<BusTimingPointSupply> getBusPosition(String date){
		List<BusTimingPointSupply> supplyList = new ArrayList<BusTimingPointSupply>();
		
		Date sysDate = DateUtils.getDateFromDate(new Date(), -1);
		String sDate = DateUtils.formatDate(sysDate);
//		String sysDate = DateUtils.getDate();
		
		// 前一天的从redis取
		if(sDate.equals(date)){
			// redis
			List<String> busPositionKeys = dataStorageToRedisService.getPositionTMKeysFromRedis(date);
			for (String redisKey : busPositionKeys) {
				BusTimingPointSupply tmp = new BusTimingPointSupply();

				String[] keySplit = redisKey.split("-");

				tmp.setSupUuid(PMSUtils.getUUID());
				tmp.setSupDate(date);
				tmp.setSupDevCode(keySplit[1]);
				tmp.setSupFlag("0");
				tmp.setDataFrom("redis");
				supplyList.add(tmp);
			}
			
			if(busPositionKeys.size() == 0){
				supplyList = busTimingPointService.selectListBusTimingPointSupply(date, false);
			}
		}else{
			// db
			// 查询当天所有设备上传的数据
			supplyList = busTimingPointService.selectListBusTimingPointSupply(date, false);
		}
		return supplyList;
	}
	
	private List<BusTimingPointSupply> getBusPositionSupply(String date){
		List<BusTimingPointSupply> supplyList = new ArrayList<BusTimingPointSupply>();
		
		// 查询所有补传标识的
		List<BusTimingPointSupply> supplyBefore = busTimingPointService.selectListBusTimingPointSupply(date, true);
		List<BusTimingPointSupply> tmpList = new ArrayList<BusTimingPointSupply>(supplyList);
		// 获取当前日期之前的所有有补传的设备
		if (tmpList.size() > 0) {

			for (BusTimingPointSupply supply : supplyBefore) {
				
				boolean hasDateDevCode = false;
				for (BusTimingPointSupply supply1 : tmpList) {
					
					if (supply1.getSupDate().equals(supply.getSupDate())
							&& supply1.getSupDevCode().equals(supply.getSupDevCode())
							) {
						hasDateDevCode = true;
						break;
					}
				}
				if(!hasDateDevCode){
					supplyList.add(supply);
				}
			}
		}else{
			supplyList.addAll(supplyBefore);
		}
		return supplyList;
	}
}
